home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / OCFSRC.PAK / OCREMVIE.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  27KB  |  1,081 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectComponents
  3. // Copyright (c) 1994, 1997 by Borland International, All Rights Reserved
  4. //
  5. // $Revision:   2.14  $
  6. //
  7. //   Implementation of TOcRemView Class
  8. //----------------------------------------------------------------------------
  9. #include <ocf/pch.h>
  10. #include <ocf/ocremvie.h>
  11. #include <ocf/ocapp.h>
  12. #include <ocf/ocstorag.h>
  13.  
  14. DIAG_DEFINE_GROUP(OcRemView, true, 2);
  15. DIAG_DECLARE_GROUP(OcRefCount);
  16.  
  17. const char  RemViewStreamName[] = "OcRemoteView";
  18.  
  19. //
  20. // Constructor for compatibility only
  21. //
  22. TOcRemView::TOcRemView(TOcDocument& doc, TRegList* regList, IUnknown* outer)
  23. :
  24.   BSiteI(0), BContainerI(0), BLSiteI(0),
  25.   State(Hidden),
  26.   Kind(DontKnow),
  27.   TOcView(doc, regList, outer)
  28. {
  29.   Init();
  30.   TRACEX(OcRefCount, 1, "TOcRemView() @" << (void*)this);
  31. }
  32.  
  33. //
  34. // New constructor that uses host interfaces
  35. //
  36. TOcRemView::TOcRemView(TOcDocument& doc,
  37.                        TOcContainerHost* ch, TOcServerHost* sh,
  38.                        TRegList* regList, IUnknown* outer)
  39. :
  40.   BSiteI(0), BContainerI(0), BLSiteI(0),
  41.   State(Hidden),
  42.   Kind(DontKnow),
  43.   TOcView(doc, ch, sh, regList, outer)
  44. {
  45.   Init();
  46.   TRACEX(OcRefCount, 1, "TOcRemView() @" << (void*)this);
  47. }
  48.  
  49. //
  50. // Do real constructor work
  51. //
  52. void
  53. TOcRemView::Init()
  54. {
  55.   // Create a site for this remote view
  56.   //
  57.   if (SUCCEEDED(OcApp.BOleComponentCreate(&BSite, (IUnknown*)(IBContainer*)this,
  58.       OcApp.IsOptionSet(amExeModule)? cidBOleSite : cidBOleInProcSite))) {
  59.  
  60.     if (SUCCEEDED(BSite->QueryInterface(IID_IBSite, &(LPVOID)BSiteI)))
  61.       Release();
  62.  
  63.     // Connect the part and the site
  64.     //
  65.     if (BSiteI) {
  66.       const char* progid = RegList->Lookup(OcApp.IsOptionSet(amDebug) ?
  67.                                            "debugprogid" : "progid");
  68.       BSiteI->Init((IBDataProvider2*)this, this, OleStr(progid), true);
  69.     }
  70.  
  71.     if (SUCCEEDED(BSite->QueryInterface(IID_IBContainer, &(LPVOID)BContainerI)))
  72.       Release();
  73.  
  74.     if (SUCCEEDED(BSite->QueryInterface(IID_IBLinkable,&(LPVOID)BLSiteI)))
  75.       BLSiteI->Release();   // avoid deadlock
  76.  
  77.     if (SUCCEEDED(BSite->QueryInterface(IID_IBApplication, &(LPVOID)BAppI)))
  78.       BAppI->Release();     // avoid deadlock
  79.   }
  80. }
  81.  
  82. //
  83. //
  84. //
  85. TOcRemView::~TOcRemView()
  86. {
  87.   // Make sure running object is unregistered
  88.   //
  89.   if (Kind == LoadFromFile && State != Closing)
  90.     EvClose();
  91.  
  92.   // Disconnect the server view host with this ocRemView
  93.   //
  94.   ServerHost->EvOcViewClose();
  95.  
  96.   // Release all helpers, but first call base class to release helpers
  97.   // BEFORE BSite is released
  98.   //
  99.   Shutdown();
  100.  
  101.   if (BSite) {
  102.     BSite->Release(); // Causes OcAppShutDown if last TOcRemView
  103.     BSite = 0;
  104.   }
  105. }
  106.  
  107. //
  108. // Should only be called by the owner/creator of this object
  109. //
  110. void
  111. TOcRemView::ReleaseObject()
  112. {
  113.   AddRef();   // cancel release, view holds a pointer but not a ref count
  114.   TOcView::ReleaseObject();
  115. }
  116.  
  117. //
  118. //
  119. //
  120. HRESULT
  121. TOcRemView::QueryObject(const IID far& iid, void far* far* iface)
  122. {
  123.   PRECONDITION(iface);
  124.   HRESULT hr;
  125.  
  126.   // interfaces
  127.   //
  128.      SUCCEEDED(hr = IBPart2_QueryInterface(this, iid, iface))
  129.   || SUCCEEDED(hr = IBDataProvider2_QueryInterface(this, iid, iface))
  130.  
  131.   // helpers
  132.   //
  133.   || (BSite && SUCCEEDED(hr = BSite->QueryInterface(iid, iface)))
  134.  
  135.   // base classes
  136.   //
  137.   || SUCCEEDED(hr = TOcView::QueryObject(iid, iface))
  138.   ;
  139.  
  140.   return hr;
  141. }
  142.  
  143.  
  144. ulong _IFUNC
  145. TOcRemView::AddRef()
  146. {
  147.   return GetOuter()->AddRef();
  148. }
  149.  
  150. ulong _IFUNC
  151. TOcRemView::Release()
  152. {
  153.   return GetOuter()->Release();
  154. }
  155.  
  156. HRESULT _IFUNC
  157. TOcRemView::QueryInterface(const GUID far& iid, void far*far* iface)
  158. {
  159.   return GetOuter()->QueryInterface(iid, iface);
  160. }
  161.  
  162. //----------------------------------------------------------------------------
  163. // IBDropDest forwarding to base
  164. //
  165. void _IFUNC
  166. TOcRemView::DragFeedback(TPoint far* p, const TRect far* r, TOcMouseAction a,
  167.                          uint cf, HRESULT& hr)
  168. {
  169.   TOcView::DragFeedback(p, r, a, cf, hr);
  170. }
  171.  
  172. //----------------------------------------------------------------------------
  173. // IBContainer overrides of TOcView implementation
  174. //
  175.  
  176. //
  177. // Show the container window
  178. //
  179. HRESULT _IFUNC
  180. TOcRemView::BringToFront()
  181. {
  182.   TOcView::BringToFront();
  183.   return HR_NOERROR;
  184. }
  185.  
  186. //
  187. // Check option flag to see if in place activation is allowed
  188. //
  189. HRESULT _IFUNC
  190. TOcRemView::AllowInPlace()
  191. {
  192.   if (IsOptionSet(voNoInPlace))
  193.     return HR_FALSE;
  194.   else if (IsOptionSet(voNoNestedInPlace) && State != OpenEditing)
  195.     return HR_FALSE;
  196.   else
  197.     return HR_NOERROR;
  198. }
  199.  
  200. //----------------------------------------------------------------------------
  201. // IBSite pass-thrus
  202.  
  203. //
  204. // Invalidate the site within the active view
  205. //
  206. void
  207. TOcRemView::Invalidate(TOcInvalidate invalid)
  208. {
  209.   if (BSiteI)
  210.     BSiteI->Invalidate(invalid);
  211. }
  212.  
  213. //
  214. // Disconnect from the client site
  215. //
  216. void
  217. TOcRemView::Disconnect()
  218. {
  219.   TRACEX(OcRemView, 1, "Disconnect() on " << (void*)this);
  220.  
  221.   if (BSiteI)
  222.     BSiteI->Disconnect();
  223. }
  224.  
  225. //
  226. // Set focus to the inplace server
  227. //
  228. bool
  229. TOcRemView::EvSetFocus(bool set)
  230. {
  231.   BSiteI->OnSetFocus(set);
  232.   return TOcView::EvSetFocus(set);
  233. }
  234.  
  235.  
  236. //----------------------------------------------------------------------------
  237. // IBDocument pass-thrus
  238.  
  239. void
  240. TOcRemView::EvClose()
  241. {
  242.   TRACEX(OcRemView, 1, "EvClose() on " << (void*)this);
  243.  
  244.   if (BSite && BLSiteI)
  245.     BLSiteI->OnRename(0, 0);
  246.  
  247.   OcDocument.Close();  // Disconnect from the parts, if any
  248.   TOcView::EvClose();
  249. }
  250.  
  251. //
  252. // Update monikers with new name
  253. //
  254. void
  255. TOcRemView::Rename()
  256. {
  257.   PRECONDITION(BLSiteI);
  258.  
  259.   TOcView::Rename();
  260.  
  261.   // Update the part's moniker
  262.   //
  263. //  BLSiteI->OnRename(BLDocumentI, OleStr(DefaultStreamName));
  264. }
  265.  
  266. //
  267. // Get the window text of the container
  268. //
  269. TString
  270. TOcRemView::GetContainerTitle()
  271. {
  272.   if (BContainerI)
  273.     return BContainerI->GetWindowTitle();
  274.   return "";
  275. }
  276.  
  277. //
  278. //  Get the initial size and position from the app
  279. //
  280. void
  281. TOcRemView::GetInitialRect(bool selection)
  282. {
  283.   TOcPartSize ps(selection);
  284.  
  285.   // See if the container has already provided a site size, & if so provide it
  286.   // as a default size to the server object.
  287.   //
  288.   bool haveSite = false;
  289.   if (BSiteI)
  290.     haveSite = SUCCEEDED(BSiteI->GetSiteRect(&ps.PartRect, 0))
  291.                && !ps.PartRect.IsEmpty();
  292.  
  293.   // Let the server app provide an initial server extent if it wants to.
  294.   //
  295.   if (!ServerHost->EvOcViewPartSize(ps)) {
  296.  
  297.     // The server has not requested a specific size. If the container has
  298.     // already provided a site size, use it. Otherwise pick an arbitrary
  299.     // non-zero size.
  300.     //
  301.     if (!haveSite) {
  302.       HDC dc = ::GetDC(0);
  303.  
  304.       // a 3" x 2" extent for server
  305.       //
  306.       ps.PartRect = TRect(0, 0,
  307.                           ::GetDeviceCaps(dc, LOGPIXELSX)*3,
  308.                           ::GetDeviceCaps(dc, LOGPIXELSY)*2);
  309.       ReleaseDC(0, dc);
  310.     }
  311.   }
  312.   Extent = ps.PartRect.Size();
  313.   Origin = ps.PartRect.TopLeft();
  314. }
  315.  
  316. //
  317. // Save remote view specific information to compound file
  318. //
  319. bool
  320. TOcRemView::Save(IStorage* storageI)
  321. {
  322.   TOcStorage Storage(storageI);
  323.  
  324.   // Create/open a stream in our storage to save part information
  325.   //
  326.   STATSTG  statstg;
  327.   if (!SUCCEEDED(Storage.Stat(&statstg, STATFLAG_NONAME)))
  328.     return false;
  329.  
  330.   TOcStream  stream(Storage, ::RemViewStreamName, true, statstg.grfMode);
  331.  
  332.   // Write TOcRemView data into stream
  333.   //
  334.   ulong count;
  335.   if (!SUCCEEDED(stream.Write(&Origin, sizeof(TPoint), &count)))
  336.     return false;
  337.  
  338.   if (!SUCCEEDED(stream.Write(&Extent, sizeof(TSize), &count)))
  339.     return false;
  340.  
  341.   return true;
  342. }
  343.  
  344. //
  345. // Load remote view specific information
  346. //
  347. bool
  348. TOcRemView::Load(IStorage* storageI)
  349. {
  350.   TOcStorage Storage(storageI);
  351.  
  352.   // Open a stream with oc part information
  353.   //
  354.   STATSTG statstg;
  355.   if (!HRSucceeded(Storage.Stat(&statstg, STATFLAG_NONAME)))
  356.     return false;
  357.  
  358.   try {
  359.     TOcStream  stream(Storage, ::RemViewStreamName, false, statstg.grfMode);
  360.  
  361.     // Read TOcPart data from stream. Server part info will be read in as
  362.     // needed after Init()
  363.     //
  364.     ulong count;
  365.     if (!HRSucceeded(stream.Read(&Origin, sizeof(TPoint), &count)))
  366.       return false;
  367.  
  368.     if (!HRSucceeded(stream.Read(&Extent, sizeof(TSize), &count)))
  369.       return false;
  370.   }
  371.   catch (TXObjComp&) {
  372.     // There is no remote view related info saved.
  373.     // This happens when saving the document while running as a stand alone
  374.     // app. But subsequently, a embed from file is executed.
  375.   }
  376.  
  377.   return true;
  378. }
  379.  
  380. //----------------------------------------------------------------------------
  381. // IBContains
  382.  
  383. //
  384. // This is called when we want to create a part from data saved
  385. // in the storage named "path"
  386. //
  387. HRESULT _IFUNC
  388. TOcRemView::Init(LPCOLESTR path)
  389. {
  390.   PRECONDITION(path);
  391.  
  392.   GetInitialRect();
  393.  
  394.   // Assume for now that we are created to load our object from a file. Kind
  395.   // will get changed later to Link if we are asked to Open()
  396.   //
  397.   Kind = LoadFromFile;
  398.  
  399.   // Read object's data from storage
  400.   //
  401.   if (!ContainerHost->EvOcViewOpenDoc(OleStr(path))) {
  402.     return HR_FAIL;
  403.   }
  404.  
  405.   // Pretend we are open editing to make sure that the doc server is attached
  406.   // to a child window in case this is a link.
  407.   //
  408.   State = OpenEditing;
  409.   ServerHost->EvOcViewAttachWindow(true);
  410.  
  411.   // If embed from file, we had to call BDocumentI->Init() to initialize
  412.   // IBApplication, but we do not want to register the drop target, therefore,
  413.   // we use a 0 for the window handle.
  414.   //
  415.   HWND oldWin = ContainerHost->EvOcGetWindow();
  416.   ContainerHost->SetWindow(0);
  417.   BDocumentI->Init(this);
  418.   ContainerHost->SetWindow(oldWin);
  419.  
  420.   // Register this document in running object table
  421.   //
  422.   OcDocument.SetName(string(OleStr(path)));
  423.   return HR_NOERROR;
  424. }
  425.  
  426. HRESULT _IFUNC
  427. TOcRemView::GetPart(IBPart far* far* parti, LPCOLESTR moniker)
  428. {
  429.   if (Kind == LoadFromFile)
  430.     Kind = Link;          // must be a link, not a transient load
  431.  
  432.   return TOcView::GetPart(parti, moniker);
  433. }
  434.  
  435. //----------------------------------------------------------------------------
  436. // IDataNegotiator implementation to eliminate ambiguity (IBPart & IBDropDest)
  437.  
  438. uint _IFUNC
  439. TOcRemView::CountFormats()
  440. {
  441.   return TOcView::CountFormats();
  442. }
  443.  
  444. HRESULT _IFUNC
  445. TOcRemView::GetFormat(uint index, TOcFormatInfo far* fmt)
  446. {
  447.   return TOcView::GetFormat(index, fmt);
  448. }
  449.  
  450. //----------------------------------------------------------------------------
  451. // IBDataProvider2 implementation
  452.  
  453. //
  454. // Request native data for pasting into client application.
  455. // This is only called at paste time (not at copy time).
  456. //
  457. HANDLE _IFUNC
  458. TOcRemView::GetFormatData(TOcFormatInfo far* fmt)
  459. {
  460.   PRECONDITION(fmt);
  461.  
  462.   TOcFormat* format = FormatList.Find(fmt->Id);
  463.   if (format) {
  464.     TOcFormatData formatData(*format);
  465.     if (ServerHost->EvOcViewClipData(formatData))
  466.       return formatData.Handle;
  467.   }
  468.   return 0;
  469. }
  470.  
  471. //
  472. // Request native data for pasting into client application.
  473. // This is only called at paste time (not at copy time).
  474. //
  475. HRESULT _IFUNC
  476. TOcRemView::SetFormatData(TOcFormatInfo far* fmt, HANDLE data, BOOL /*release*/)
  477. {
  478.   PRECONDITION(fmt);
  479.   PRECONDITION(data);
  480.  
  481.   TOcFormat* format = FormatList.Find(fmt->Id);
  482.   if (format) {
  483.     TOcFormatData formatData(*format, 0, data);
  484.     if (ServerHost->EvOcViewSetData(formatData))
  485.       return HR_NOERROR;
  486.   }
  487.   return HR_FAIL;
  488. }
  489.  
  490. #if defined(BI_PLAT_WIN16)
  491.   extern "C" HRGN FAR PASCAL GetClipRgn(HDC);  // GDI.173
  492. #endif
  493.  
  494. //
  495. // Render the view in the DC provided. May be a MetaFile
  496. // Packup all the args & forward message to real view to paint
  497. //
  498. HRESULT _IFUNC
  499. TOcRemView::Draw(HDC dc, const RECTL far*  pos, const RECTL far* clip,
  500.                  TOcAspect aspect, TOcDraw bd)
  501. {
  502.   PRECONDITION(dc);
  503.   bool metafile = ::GetDeviceCaps(dc, TECHNOLOGY) == DT_METAFILE;
  504.  
  505.   // Rely on the BOle shading
  506.   //
  507.   if (bd == drShadingOnly)
  508.     return HR_NOERROR;
  509.  
  510.   TRect p((int)pos->left, (int)pos->top, (int)pos->right, (int)pos->bottom);
  511.   TRect c((int)clip->left, (int)clip->top, (int)clip->right, (int)clip->bottom);
  512.  
  513.   TPoint oldViewOrg;
  514.   TPoint oldWinOrg;
  515.   TSize  oldViewExt;
  516.   TSize  oldWinExt;
  517.   int    oldMapMode;
  518.   HRGN   hRgn;
  519.  
  520.   if (metafile) {
  521.     p.SetEmpty();
  522.     ::SetMapMode(dc, MM_ANISOTROPIC);
  523.  
  524.     ::SetWindowExtEx(dc, Extent.cx, Extent.cy, 0);
  525.     ::SetWindowOrgEx(dc, 0, 0, 0);
  526.   }
  527.   else if (!OcApp.IsOptionSet(amExeModule)) {
  528.     if (p.Width() != Extent.cx || p.Height() != Extent.cy) {
  529.       TOcScaleFactor scaleFactor(p, Extent);
  530.       ServerHost->EvOcViewSetScale(scaleFactor);
  531.     }
  532. #if defined(BI_PLAT_WIN16)
  533.     hRgn = ::GetClipRgn(dc);
  534. #else
  535.     hRgn = ::CreateRectRgn(0, 0, 0, 0);
  536.     ::GetClipRgn(dc, hRgn);
  537. #endif
  538.     ::LPtoDP(dc, (TPoint*)&p, 2);
  539.     ::LPtoDP(dc, (TPoint*)&c, 2);
  540.     ::IntersectClipRect(dc, c.left, c.top, c.right, c.bottom);
  541.  
  542.     ::SetViewportOrgEx(dc, p.left, p.top, &oldViewOrg);
  543.     ::GetWindowOrgEx(dc, &oldWinOrg);
  544.     ::GetWindowExtEx(dc, &oldWinExt);
  545.     ::GetViewportExtEx(dc, &oldViewExt);
  546.     oldMapMode  = ::GetMapMode(dc);
  547.   }
  548.  
  549.   p.Normalize();
  550.   c.Normalize();
  551.  
  552.   TOcViewPaint vp = { dc, &p, &c, (TOcAspect)aspect, false, 0, 0 };
  553.   bool result = ServerHost->EvOcViewPaint(vp);
  554.  
  555.   // Restore the dc attributes
  556.   //
  557.   if (!metafile && !OcApp.IsOptionSet(amExeModule)) {
  558.     ::SetMapMode(dc, oldMapMode);
  559.     ::SetViewportOrgEx(dc, oldViewOrg.x, oldViewOrg.y, 0);
  560.     ::SetWindowOrgEx(dc, oldWinOrg.x, oldWinOrg.y, 0);
  561.     ::SetViewportExtEx(dc, oldViewExt.cx, oldViewExt.cy, 0);
  562.     ::SetWindowExtEx(dc, oldWinExt.cx, oldWinExt.cy, 0);
  563.     ::SelectClipRgn(dc, hRgn);
  564. #if !defined(BI_PLAT_WIN16)
  565.     ::DeleteObject(hRgn);
  566. #endif
  567.   }
  568.  
  569.   return HRFailIfZero(result);
  570. }
  571.  
  572. //
  573. // Return the 'size' of the document that this view in on
  574. //
  575. HRESULT _IFUNC
  576. TOcRemView::GetPartSize(TSize far* size)
  577. {
  578.   *size = Extent;
  579.   return HR_NOERROR;
  580. }
  581.  
  582. //
  583. // Save the document that we are a view on
  584. //
  585. HRESULT _IFUNC
  586. TOcRemView::Save(IStorage* storage, BOOL sameAsLoad, BOOL remember)
  587. {
  588.   PRECONDITION(storage);
  589.  
  590.   TOcSaveLoad ocSave(storage, ToBool(sameAsLoad), ToBool(remember));
  591.   return HRFailIfZero(ServerHost->EvOcViewSavePart(ocSave));
  592. }
  593.  
  594. //----------------------------------------------------------------------------
  595. // IBPart2 implementation
  596.  
  597. //
  598. // Load the associated document and activate the remote view
  599. //
  600. HRESULT _IFUNC
  601. TOcRemView::Init(IBSite far*, TOcInitInfo far* initInfo)
  602. {
  603.   PRECONDITION(initInfo);
  604.  
  605.   // Now we know that we are a normal embedding
  606.   //
  607.   Kind = Embedding;
  608.  
  609.   // If existing document, notify the app to read it in.
  610.   //
  611.   if (initInfo->Where == iwStorage) {
  612.     TOcSaveLoad ocLoad(initInfo->Storage, true, true);
  613.     if (!ServerHost->EvOcViewLoadPart(ocLoad))
  614.       return HR_FAIL;
  615.   }
  616.   else if (initInfo->Where == iwNew)
  617.     GetInitialRect();
  618.  
  619.   // Show & activate this embedded object
  620.   //
  621.   Show(true);
  622.   Activate(true);
  623.  
  624.   return HR_NOERROR;
  625. }
  626.  
  627. //
  628. // Close the remote view window, & if canShutDown is true, try to close the
  629. // server app too
  630. //
  631. HRESULT _IFUNC
  632. TOcRemView::Close()
  633. {
  634.   TRACEX(OcRemView, 1, "Close() on " << (void*)this <<
  635.          " Closing:" << (int)ToBool(State==Closing) << " Win:" << hex <<
  636.          (uint)ServerHost->EvOcGetWindow());
  637.  
  638.   // Keep DLL server in memory until its ref count goes to 0
  639.   //
  640.   if (State != Closing && OcApp.IsOptionSet(amExeMode)) {
  641.     EvClose();
  642.   }
  643.  
  644.   // Remember that we are closing so that we don't do Close() again
  645.   //
  646.   State = Closing;
  647.  
  648.   return HR_NOERROR;
  649. }
  650.  
  651. //
  652. // Query to determine if this server view can open in place
  653. //
  654. HRESULT _IFUNC
  655. TOcRemView::CanOpenInPlace()
  656. {
  657.   if (IsOptionSet(voNoInPlaceServer))
  658.     return HR_FALSE;    // Force server to open edit
  659.   else
  660.     return HR_NOERROR;  // allow in place activation
  661. }
  662.  
  663. //
  664. // Set a new position for our document within its container
  665. //
  666. HRESULT _IFUNC
  667. TOcRemView::SetPartPos(TRect far* r)
  668. {
  669.   Origin = *(POINT*)&r->left;
  670.  
  671.   CHECK(BSiteI);
  672.   TOcScaleInfo scale;
  673.   BSiteI->GetZoom(&scale);
  674.   TOcScaleFactor scaleFactor(scale);
  675.  
  676.   // No scaling
  677.   //
  678.   if (scale.xN == 1 && scale.yN == 1) {
  679.     scaleFactor.SiteSize.cx = scaleFactor.PartSize.cx = r->right - r->left;
  680.     scaleFactor.SiteSize.cy = scaleFactor.PartSize.cy = r->bottom - r->top;
  681.   }
  682.  
  683.   ::MoveWindow(GetWindow(), r->left, r->top,
  684.                scaleFactor.SiteSize.cx, scaleFactor.SiteSize.cy, true);
  685.  
  686.   ServerHost->EvOcViewSetScale(scaleFactor);
  687.  
  688.   return HR_NOERROR;
  689. }
  690.  
  691. HRESULT _IFUNC
  692. TOcRemView::SetPartSize(TSize far* size)
  693. {
  694.   Extent = *size;
  695.   return HR_NOERROR;
  696. }
  697.  
  698. //
  699. // Activate this view
  700. //
  701. HRESULT _IFUNC
  702. TOcRemView::Activate(BOOL activate)
  703. {
  704.   if (activate && GetWindow())
  705.     ::SetFocus(GetWindow());
  706.   return HR_NOERROR;
  707. }
  708.  
  709. //
  710. // Show/Hide the server view window
  711. //
  712. HRESULT _IFUNC
  713. TOcRemView::Show(BOOL show)
  714. {
  715.   if (GetWindow())
  716.     ::ShowWindow(GetWindow(), show ? SW_SHOW : SW_HIDE);
  717.   return HR_NOERROR;
  718. }
  719.  
  720. //
  721. // Start or end open editing
  722. // Work with the window Z-order and parenting
  723. //
  724. HRESULT _IFUNC
  725. TOcRemView::Open(BOOL open)
  726. {
  727.   if (open) {
  728.     // Just show the window, if it's already active
  729.     //
  730.     if (State == InPlaceActive) {
  731.       HWND contWin = BAppI->GetWindow();
  732.       ::BringWindowToTop(contWin);
  733.     }
  734.     else {
  735.       State = OpenEditing;    // we now transition into open edit state
  736.       if (Kind == LoadFromFile)
  737.         Kind = Link;          // must be a link, not a transient load
  738.  
  739.       // Register drag&drop target
  740.       //
  741.       BDocumentI->Init(this);
  742.  
  743.       // Forward event to app to let it attach the window to an appropriate
  744.       // frame
  745.       //
  746.       ServerHost->EvOcViewAttachWindow(true);
  747.       BringToFront();
  748.  
  749.       // Build up open edit caption in the form "<menuname> in <containername>"
  750.       //
  751.       if (RegList && Kind != Link) {
  752.         string newTitle = (*RegList)["menuname"];
  753.         char in[32];
  754.         ::LoadString(_hInstance, IDS_IN, in, sizeof in);
  755.         newTitle += in;
  756.         LPCOLESTR str = BContainerI->GetWindowTitle();
  757.         if (str)
  758.           newTitle += OleStr(str);
  759.         ServerHost->EvOcViewSetTitle(newTitle.c_str());
  760.       }
  761.       else {
  762.         ServerHost->EvOcViewSetTitle(NULL); // if link, caption is filename
  763.       }
  764.     }
  765.   }
  766.   else {
  767.     // Unregister drag&drop target
  768.     //
  769.     BDocumentI->OnClose();
  770.  
  771.     // Reparent back to the real parent
  772.     //
  773.     ServerHost->EvOcViewAttachWindow(false);
  774.   }
  775.   return HR_NOERROR;
  776. }
  777.  
  778. //
  779. // Enumerate the verbs for our document
  780. //
  781. HRESULT _IFUNC
  782. TOcRemView::EnumVerbs(TOcVerb far*)
  783. {
  784.   return HR_FAIL;  // Not called on BOle parts
  785. }
  786.  
  787. //
  788. // Perform a verb on our document
  789. //
  790. HRESULT _IFUNC
  791. TOcRemView::DoVerb(uint verb)
  792. {
  793.   return HRFailIfZero(ServerHost->EvOcViewDoVerb(verb));
  794. }
  795.  
  796. //
  797. // Open or close this view as an in-place edit session. If hWndParent is 0,
  798. // then in-place is closing
  799. //
  800. HWND _IFUNC
  801. TOcRemView::OpenInPlace(HWND hWndParent)
  802. {
  803.   if (hWndParent) {
  804.     State = InPlaceActive;  // transition into in-place-active state
  805.  
  806.     // Register drag&drop target
  807.     //
  808.     BDocumentI->Init(this);
  809.  
  810.     ::SetParent(GetWindow(), hWndParent);
  811.   }
  812.   else {
  813.     State = Hidden;  // transition back into normal, hidden state
  814.     BDocumentI->OnClose();
  815.  
  816.     // Deactivate in-place active object, if any
  817.     //
  818.     if (ActivePart)
  819.       ActivePart->Activate(false);
  820.  
  821.     // Set back to real parent and don't show it
  822.     //
  823.     if (!ServerHost->EvOcViewAttachWindow(false)) {
  824.       Show(false);
  825.       ::SetParent(GetWindow(), OcApp.GetWindow());
  826.     }
  827.   }
  828.   return GetWindow();
  829. }
  830.  
  831. //
  832. // Insert the server's menus into the shared menubar
  833. //
  834. HRESULT _IFUNC
  835. TOcRemView::InsertMenus(HMENU hMenu, TOcMenuWidths far* omw)
  836. {
  837.   PRECONDITION(omw && hMenu);
  838.  
  839.   TOcMenuDescr md;
  840.   md.HMenu = hMenu;
  841.  
  842.   int i;
  843.   for (i = 0; i < 6; i++) {
  844.     md.Width[i] = (int)omw->Width[i];
  845.     i++;
  846.     md.Width[i] = 0;  // make sure the server's are zeroed
  847.     omw->Width[i] = 0;
  848.   }
  849.  
  850.   if (!ServerHost->EvOcViewInsMenus(md))
  851.     return HR_FAIL;
  852.  
  853.   for (i = 0; i < 6; i++)
  854.     omw->Width[i] = md.Width[i];
  855.  
  856.   return HR_NOERROR;
  857. }
  858.  
  859. //
  860. // Retrieve rectangle info about the toolbars
  861. //
  862. static void
  863. getTBRects(TOcToolBarInfo far& tbi,
  864.             TRect& ttbr, TRect& ltbr, TRect& btbr, TRect& rtbr, TRect& border)
  865. {
  866.   if (tbi.HLeftTB)
  867.     ::GetWindowRect(tbi.HLeftTB, <br);
  868.   else
  869.     ltbr.Set(0,0,0,0);
  870.   if (tbi.HTopTB)
  871.     ::GetWindowRect(tbi.HTopTB, &ttbr);
  872.   else
  873.     ttbr.Set(0,0,0,0);
  874.   if (tbi.HRightTB)
  875.     ::GetWindowRect(tbi.HRightTB, &rtbr);
  876.   else
  877.     rtbr.Set(0,0,0,0);
  878.   if (tbi.HBottomTB)
  879.     ::GetWindowRect(tbi.HBottomTB, &btbr);
  880.   else
  881.     btbr.Set(0,0,0,0);
  882.   border.Set(ltbr.Width() ? ltbr.Width()-1 : 0,
  883.              ttbr.Height() ? ttbr.Height()-1 : 0,
  884.              rtbr.Width() ? rtbr.Width()-1 : 0,
  885.              btbr.Height() ? btbr.Height()-1 : 0);
  886. }
  887.  
  888. //
  889. // Actually parent & position the toolbars in the container frame.
  890. // Assume all the toolbars have WS_BORDER style & overlaps accordingly
  891. //
  892. static void
  893. adjustTBPos(TOcToolBarInfo far& tbi, const TRect& contFrameR, bool setParent,
  894.              const TRect& ttbr, const TRect& ltbr,
  895.              const TRect& btbr, const TRect& rtbr,
  896.              const TRect& border)
  897. {
  898.   if (tbi.HLeftTB) {
  899.     ::MoveWindow(tbi.HLeftTB, -1, -1+border.top, ltbr.Width(),
  900.                  contFrameR.Height()+2-border.top-border.bottom, true);
  901.     if (setParent) {
  902.       ::SetParent(tbi.HLeftTB, tbi.HFrame);
  903.       ::ShowWindow(tbi.HLeftTB, SW_NORMAL);
  904.     }
  905.   }
  906.   if (tbi.HTopTB) {
  907.     ::MoveWindow(tbi.HTopTB, -1, -1, contFrameR.Width()+2, ttbr.Height(),
  908.                  true);
  909.     if (setParent) {
  910.       ::SetParent(tbi.HTopTB, tbi.HFrame);
  911.       ::ShowWindow(tbi.HTopTB, SW_NORMAL);
  912.     }
  913.   }
  914.   if (tbi.HRightTB) {
  915.     ::MoveWindow(tbi.HRightTB, contFrameR.right-rtbr.Width()+1, -1+border.top,
  916.                  rtbr.Width(), contFrameR.Height()+2-border.top-border.bottom,
  917.                  true);
  918.     if (setParent) {
  919.       ::SetParent(tbi.HRightTB, tbi.HFrame);
  920.       ::ShowWindow(tbi.HRightTB, SW_NORMAL);
  921.     }
  922.   }
  923.   if (tbi.HBottomTB) {
  924.     ::MoveWindow(tbi.HBottomTB, -1, contFrameR.bottom-btbr.Height()+1,
  925.                  contFrameR.Width()+2, btbr.Height(), true);
  926.     if (setParent) {
  927.       ::SetParent(tbi.HBottomTB, tbi.HFrame);
  928.       ::ShowWindow(tbi.HBottomTB, SW_NORMAL);
  929.     }
  930.   }
  931. }
  932.  
  933. //
  934. // Show or hide the tool windows used by our view
  935. //
  936. HRESULT _IFUNC
  937. TOcRemView::ShowTools(BOOL show)
  938. {
  939.   TOcToolBarInfo far& tbi = ToolBarInfo;
  940.   tbi.Show = show;
  941.   tbi.HTopTB = tbi.HLeftTB = tbi.HBottomTB = tbi.HRightTB = 0;
  942.   if (show)
  943.     tbi.HFrame = BAppI->GetWindow();  // Container's frame
  944.   else
  945.     tbi.HFrame = OcApp.GetWindow();   // This server's frame
  946.  
  947.   // Let the view create/destroy its toolbars & fill them in for us to work
  948.   // with. View may also change the HFrame for special purposes
  949.   //
  950.   if (!ServerHost->EvOcViewShowTools(tbi))
  951.     return HR_FAIL;
  952.  
  953.   // Assist view in showing toobars by negotiating, parenting to the container
  954.   // frame & showing the provided toolbars
  955.   //
  956.   if (show) {
  957.     TRect ltbr;
  958.     TRect ttbr;
  959.     TRect rtbr;
  960.     TRect btbr;
  961.     TRect border;
  962.     getTBRects(tbi, ltbr, ttbr, rtbr, btbr, border);
  963.  
  964.     // Request the desired border space from the container. Scale back requests
  965.     // as needed if container denies requests.
  966.     //
  967.     int i;
  968.     for (i = 0; i < 3; i++) {
  969.       if (!SUCCEEDED(BAppI->RequestBorderSpace(&border))) {
  970.         switch (i) {
  971.           case 0:
  972.             border.bottom = 0;
  973.             tbi.HBottomTB = 0;
  974.             break;
  975.           case 1:
  976.             border.right = 0;
  977.             tbi.HRightTB = 0;
  978.             break;
  979.           case 2:
  980.             border.left = 0;
  981.             tbi.HLeftTB = 0;
  982.         }
  983.       }
  984.       else
  985.         break;
  986.     }
  987.     if (i == 3 || !SUCCEEDED(BAppI->SetBorderSpace(&border)))
  988.       return HR_FAIL;  // don't know why it failed. Give up
  989.  
  990.     TRect contFrameR;
  991.     BAppI->GetWindowRect(&contFrameR);
  992.     adjustTBPos(tbi, contFrameR, true, ltbr, ttbr, rtbr, btbr, border);
  993.   }
  994.   // Assist view in hiding toobars by reparenting them to frame (defaults to
  995.   // this server) & hiding them
  996.   //
  997.   else {
  998.     if (tbi.HLeftTB) {
  999.       ::SetParent(tbi.HLeftTB, tbi.HFrame);
  1000.       ::ShowWindow(tbi.HLeftTB, SW_HIDE);
  1001.     }
  1002.     if (tbi.HTopTB) {
  1003.       ::SetParent(tbi.HTopTB, tbi.HFrame);
  1004.       ::ShowWindow(tbi.HTopTB, SW_HIDE);
  1005.     }
  1006.     if (tbi.HRightTB) {
  1007.       ::SetParent(tbi.HRightTB, tbi.HFrame);
  1008.       ::ShowWindow(tbi.HRightTB, SW_HIDE);
  1009.     }
  1010.     if (tbi.HBottomTB) {
  1011.       ::SetParent(tbi.HBottomTB, tbi.HFrame);
  1012.       ::ShowWindow(tbi.HBottomTB, SW_HIDE);
  1013.     }
  1014.   }
  1015.   return HR_NOERROR;
  1016. }
  1017.  
  1018. //
  1019. // A container window has resized. Perform any necessary adjustment of our
  1020. // tools.
  1021. //
  1022. void _IFUNC
  1023. TOcRemView::FrameResized(const TRect far* contFrameR, BOOL isMainFrame)
  1024. {
  1025.   if (!isMainFrame)
  1026.     return;
  1027.  
  1028.   TRect ltbr;
  1029.   TRect ttbr;
  1030.   TRect rtbr;
  1031.   TRect btbr;
  1032.   TRect border;
  1033.   getTBRects(ToolBarInfo, ltbr, ttbr, rtbr, btbr, border);
  1034.   adjustTBPos(ToolBarInfo, *contFrameR, false, ltbr, ttbr, rtbr, btbr, border);
  1035. }
  1036.  
  1037. //
  1038. // Let the server provide drag feedback
  1039. //
  1040. HRESULT _IFUNC
  1041. TOcRemView::DragFeedback(TPoint far* where, BOOL /*nearScroll*/)
  1042. {
  1043.   PRECONDITION(where);
  1044.  
  1045.   TPoint awhere(*where);
  1046.   TOcDragDrop dd = { 0, &awhere, 0 };
  1047.   return HRFailIfZero(ServerHost->EvOcViewDrag(dd));
  1048. }
  1049.  
  1050. //
  1051. // Optional palette query for
  1052. //
  1053. HRESULT _IFUNC
  1054. TOcRemView::GetPalette(LOGPALETTE far* far* palette)
  1055. {
  1056.   PRECONDITION(palette);
  1057.  
  1058.   return HRFailIfZero(ServerHost->EvOcViewGetPalette(palette));
  1059. }
  1060.  
  1061. HRESULT _IFUNC
  1062. TOcRemView::SetHost(IBContainer far*)
  1063. {
  1064.   return HR_FAIL;  // Not called on BOle parts.
  1065. }
  1066.  
  1067. HRESULT _IFUNC
  1068. TOcRemView::DoQueryInterface(const IID far& iid, void far* far* iface)
  1069. {
  1070.   PRECONDITION(iface);
  1071.  
  1072.   return TOcView::QueryInterface(iid, iface);  // Unused on server side
  1073. }
  1074.  
  1075. LPOLESTR _IFUNC
  1076. TOcRemView::GetName(TOcPartName)
  1077. {
  1078.   return 0;  // not called on BOle parts
  1079. }
  1080.  
  1081.